package track2.bayes;
/*
 * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DescribeAvailabilityZonesResult;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.DomainMetadataRequest;
import com.amazonaws.services.simpledb.model.DomainMetadataResult;
import com.amazonaws.services.simpledb.model.ListDomainsRequest;
import com.amazonaws.services.simpledb.model.ListDomainsResult;

/**
 * Welcome to your new AWS Java SDK based project!
 * 
 * This class is meant as a starting point for your console-based application
 * that makes one or more calls to the AWS services supported by the Java SDK,
 * such as EC2, SimpleDB, and S3.
 * 
 * In order to use the services in this sample, you need:
 * 
 * - A valid Amazon Web Services account. You can register for AWS at:
 * https://aws-portal.amazon.com/gp/aws/developer/registration/index.html
 * 
 * - Your account's Access Key ID and Secret Access Key:
 * http://aws.amazon.com/security-credentials
 * 
 * - A subscription to Amazon EC2. You can sign up for EC2 at:
 * http://aws.amazon.com/ec2/
 * 
 * - A subscription to Amazon SimpleDB. You can sign up for Simple DB at:
 * http://aws.amazon.com/simpledb/
 * 
 * - A subscription to Amazon S3. You can sign up for S3 at:
 * http://aws.amazon.com/s3/
 */
public class AwsConsoleApp {

	/*
	 * Important: Be sure to fill in your AWS access credentials in the
	 * AwsCredentials.properties file before you try to run this sample.
	 * http://aws.amazon.com/security-credentials
	 */

	static AmazonEC2 ec2;
	static AmazonS3 s3;
	static AmazonSimpleDB sdb;

	/**
	 * The only information needed to create a client are security credentials
	 * consisting of the AWS Access Key ID and Secret Access Key. All other
	 * configuration, such as the service endpoints, are performed
	 * automatically. Client parameters, such as proxies, can be specified in an
	 * optional ClientConfiguration object when constructing a client.
	 * 
	 * @see com.amazonaws.auth.BasicAWSCredentials
	 * @see com.amazonaws.auth.PropertiesCredentials
	 * @see com.amazonaws.ClientConfiguration
	 */
	private static void init() throws Exception {
		AWSCredentials credentials = new PropertiesCredentials(
				AwsConsoleApp.class
						.getResourceAsStream("AwsCredentials.properties"));

		ec2 = new AmazonEC2Client(credentials);
		s3 = new AmazonS3Client(credentials);
		sdb = new AmazonSimpleDBClient(credentials);
	}

	public static void main(String[] args) throws Exception {

		System.out.println("===========================================");
		System.out.println("Welcome to the AWS Java SDK!");
		System.out.println("===========================================");

		init();

		/*
		 * Amazon EC2
		 * 
		 * The AWS EC2 client allows you to create, delete, and administer
		 * instances programmatically.
		 * 
		 * In this sample, we use an EC2 client to get a list of all the
		 * availability zones, and all instances sorted by reservation id.
		 */
		try {
			DescribeAvailabilityZonesResult availabilityZonesResult = ec2
					.describeAvailabilityZones();
			System.out.println("You have access to "
					+ availabilityZonesResult.getAvailabilityZones().size()
					+ " Availability Zones.");

			DescribeInstancesResult describeInstancesRequest = ec2
					.describeInstances();
			List<Reservation> reservations = describeInstancesRequest
					.getReservations();
			Set<Instance> instances = new HashSet<Instance>();

			for (Reservation reservation : reservations) {
				instances.addAll(reservation.getInstances());
			}

			System.out.println("You have " + instances.size()
					+ " Amazon EC2 instance(s) running.");
		} catch (AmazonServiceException ase) {
			System.out.println("Caught Exception: " + ase.getMessage());
			System.out.println("Reponse Status Code: " + ase.getStatusCode());
			System.out.println("Error Code: " + ase.getErrorCode());
			System.out.println("Request ID: " + ase.getRequestId());
		}

		/*
		 * Amazon SimpleDB
		 * 
		 * The AWS SimpleDB client allows you to query and manage your data
		 * stored in SimpleDB domains (similar to tables in a relational DB).
		 * 
		 * In this sample, we use a SimpleDB client to iterate over all the
		 * domains owned by the current user, and add up the number of items
		 * (similar to rows of data in a relational DB) in each domain.
		 */
		try {
			ListDomainsRequest sdbRequest = new ListDomainsRequest()
					.withMaxNumberOfDomains(100);
			ListDomainsResult sdbResult = sdb.listDomains(sdbRequest);

			int totalItems = 0;
			for (String domainName : sdbResult.getDomainNames()) {
				DomainMetadataRequest metadataRequest = new DomainMetadataRequest()
						.withDomainName(domainName);
				DomainMetadataResult domainMetadata = sdb
						.domainMetadata(metadataRequest);
				totalItems += domainMetadata.getItemCount();
			}

			System.out.println("You have " + sdbResult.getDomainNames().size()
					+ " Amazon SimpleDB domain(s)" + "containing a total of "
					+ totalItems + " items.");
		} catch (AmazonServiceException ase) {
			System.out.println("Caught Exception: " + ase.getMessage());
			System.out.println("Reponse Status Code: " + ase.getStatusCode());
			System.out.println("Error Code: " + ase.getErrorCode());
			System.out.println("Request ID: " + ase.getRequestId());
		}

		/*
		 * Amazon S3
		 * 
		 * The AWS S3 client allows you to manage buckets and programmatically
		 * put and get objects to those buckets.
		 * 
		 * In this sample, we use an S3 client to iterate over all the buckets
		 * owned by the current user, and all the object metadata in each
		 * bucket, to obtain a total object and space usage count. This is done
		 * without ever actually downloading a single object -- the requests
		 * work with object metadata only.
		 */
		S3Object object = s3.getObject(new GetObjectRequest("bigmlplj",
				"track2/test.txt"));
		BufferedReader reader = new BufferedReader(new InputStreamReader(object.getObjectContent()));
		String read;
		while ((read = reader.readLine()) != null) {
			System.out.println(read);
		}
		try {
			List<Bucket> buckets = s3.listBuckets();
			long totalSize = 0;
			int totalItems = 0;
			for (Bucket bucket : buckets) {
				/*
				 * In order to save bandwidth, an S3 object listing does not
				 * contain every object in the bucket; after a certain point the
				 * S3ObjectListing is truncated, and further pages must be
				 * obtained with the AmazonS3Client.listNextBatchOfObjects()
				 * method.
				 */
				ObjectListing objects = s3.listObjects(bucket.getName());
				do {
					for (S3ObjectSummary objectSummary : objects
							.getObjectSummaries()) {
						totalSize += objectSummary.getSize();
						totalItems++;
					}
					objects = s3.listNextBatchOfObjects(objects);
				} while (objects.isTruncated());
			}

			System.out.println("You have " + buckets.size()
					+ " Amazon S3 bucket(s), " + "containing " + totalItems
					+ " objects with a total size of " + totalSize + " bytes.");
		} catch (AmazonServiceException ase) {
			/*
			 * AmazonServiceExceptions represent an error response from an AWS
			 * services, i.e. your request made it to AWS, but the AWS service
			 * either found it invalid or encountered an error trying to execute
			 * it.
			 */
			System.out.println("Error Message:    " + ase.getMessage());
			System.out.println("HTTP Status Code: " + ase.getStatusCode());
			System.out.println("AWS Error Code:   " + ase.getErrorCode());
			System.out.println("Error Type:       " + ase.getErrorType());
			System.out.println("Request ID:       " + ase.getRequestId());
		} catch (AmazonClientException ace) {
			/*
			 * AmazonClientExceptions represent an error that occurred inside
			 * the client on the local host, either while trying to send the
			 * request to AWS or interpret the response. For example, if no
			 * network connection is available, the client won't be able to
			 * connect to AWS to execute a request and will throw an
			 * AmazonClientException.
			 */
			System.out.println("Error Message: " + ace.getMessage());
		}
	}
}
